<template>
    <div id="code">
        <div class="repo_left">
            <div class="repo_left_bar">
                <div class="repo_left_bar_head" @click="goToUserPage">
                    <el-image class="xiaomi" :src="head" fit="cover"></el-image>
                </div>
                <div class="repo_left_bar_item">
                    <div class="repo_left_bar_value">{{repoInfo.open_issues_count}}</div>
                    <div class="repo_left_bar_key">Issues</div>
                </div>
                <div class="repo_left_bar_item">
                    <div class="repo_left_bar_key">Pull Request</div>
                </div>
                <div class="repo_left_bar_item">
                    <div class="repo_left_bar_value">{{repoInfo.stargazers_count}}</div>
                    <div class="repo_left_bar_key">Stars</div>
                </div>
                <div class="repo_left_bar_item">
                    <div class="repo_left_bar_value">{{repoInfo.forks_count}}</div>
                    <div class="repo_left_bar_key">Forks</div>
                </div>
                <div class="repo_left_bar_item">
                    <div class="repo_left_bar_value">{{repoInfo.watchers_count}}</div>
                    <div class="repo_left_bar_key">Watches</div>
                </div>
            </div>
            <div class="repo_left_tree">
                <div class="repo_left_tree_title">代码目录
                    <el-dropdown class="repo_left_tree_branch" @command="handleBranchChanged">
                        <span class="el-dropdown-link">
                            {{nowBranch}}<i class="el-icon-arrow-down el-icon--right"></i>
                        </span>
                        <el-dropdown-menu slot="dropdown">
                            <el-dropdown-item v-for="(item) in branchList" :command="item.name">{{item.name}}
                            </el-dropdown-item>
                        </el-dropdown-menu>
                    </el-dropdown>

                </div>
                <div class="repo_left_tree_body">
                    <el-tree :data="treeData" :props="defaultProps" @node-click="handleNodeClick"
                        icon-class="iconfont icon-changyongtubiao-mianxing-43"></el-tree>
                </div>
            </div>
        </div>
        <div class="repo_right">
            <div class="repo_right_right_title"></div>
            <el-tabs type="card" closable v-model="selectedFileIndex" @tab-remove="removeOpenFile"
                @tab-click="handleTabClick">
                <el-tab-pane :key="item.sha" v-for="(item, index) in openFiles"
                    :label="(item.label+'($'+item.$treeNodeId+')')" :name="item.sha">
                </el-tab-pane>
            </el-tabs>
            <div class="repo_right_editor" id="editor"></div>
        </div>
        <div class="repo_footer" v-if="repoInfo">
            <div class="repo_footer_item" v-if="repoInfo.recommend">
                <i class="iconfont icon-gitee"></i>推荐项目
            </div>
            <div class="repo_footer_item">
                仓库: <a :href="'https://gitee.com/'+repoInfo.full_name" target="_blank">{{repoInfo.human_name}}</a>
            </div>
            <div class="repo_footer_item">
                {{repoInfo.language}}
            </div>
            <div class="repo_footer_item">
                {{repoInfo.license}}
            </div>
            <div class="repo_footer_item">
                最后更新: {{friendlyTime(repoInfo.pushed_at)}}
            </div>
            <div class="repo_footer_right">
                <div class="repo_footer_item" v-if="repoInfo.homepage">
                    主页: <a :href="repoInfo.homepage" target="_blank">{{repoInfo.homepage}}</a>
                </div>
                <div class="user_footer_item">
                    By <router-link to="/">Gitee.Info</router-link>
                </div>
            </div>
        </div>
    </div>
</template>
<style>
    .el-tree-node__label {
        font-size: 12px;
    }

    .repo_footer {
        background-color: #0075c3;
        position: absolute;
        left: 0;
        right: 0;
        height: 28px;
        line-height: 28px;
        bottom: 0;
        font-size: 12px;
        padding: 0px 10px;
        color: white;
    }

    .repo_footer_item {
        display: inline-block;
        cursor: pointer;
        padding: 0px 5px;
        vertical-align: middle;
    }

    .repo_footer_item:hover {
        background-color: #2e97dd;
    }

    .repo_footer_item .iconfont {
        display: inline-block;
        font-size: 12px;
    }

    .repo_footer a {
        color: white;
        text-decoration: none;
    }

    .repo_footer a:hover {
        color: yellow;
    }

    .repo_footer_right {
        position: absolute;
        right: 10px;
        top: 0;
        bottom: 0;
    }

    .repo_left {
        position: absolute;
        left: 0;
        top: 0;
        bottom: 28px;
        width: 260px;
        border-right: 3px solid #222;
    }

    .repo_left_bar {
        position: absolute;
        left: 0;
        top: 0;
        bottom: 0;
        width: 60px;
        background-color: #222;
    }

    .repo_left_bar_item {
        text-align: center;
        padding: 10px 0px;
        cursor: pointer;
    }

    .repo_left_bar_item:hover {
        background-color: #333;
    }

    .repo_left_bar_value {
        font-size: 14px;
    }

    .repo_left_bar_key {
        font-size: 12px;
        color: #666;
    }

    .repo_left_bar_head {
        padding: 10px;
        margin-bottom: 10px;
    }

    .repo_left_bar_head img {
        width: 40px;
        height: 40px;
        border-radius: 10px;
        cursor: pointer;
    }

    .repo_left_tree {
        position: absolute;
        left: 60px;
        top: 0;
        bottom: 0;
        right: 0;
        background-color: #222;
    }

    .repo_left_tree_title {
        font-size: 12px;
        color: #666;
        background-color: #222;
        padding: 8px 5px;
        position: absolute;
        left: 0;
        right: 0;
        top: 0;
    }

    .repo_left_tree_branch {
        position: absolute;
        right: 5px;
        top: 10px;
        color: #fff;
        cursor: pointer;
        font-size: 12px;
    }

    .repo_left_tree_branch:hover {
        color: yellow;
    }

    .repo_left_tree_body {
        position: absolute;
        left: 0;
        right: 0;
        top: 30px;
        bottom: 10px;
        overflow: hidden;
        overflow-y: auto;
    }

    .repo_right {
        position: absolute;
        left: 263px;
        top: 0;
        bottom: 28px;
        right: 0;
        background-color: #222;
    }

    .repo_right_editor {
        position: absolute;
        left: 0;
        right: 0;
        top: 41px;
        bottom: 0;
        overflow: auto;
    }

    .el-tabs--card>.el-tabs__header .el-tabs__item.is-active,
    .el-tabs--card>.el-tabs__header .el-tabs__nav {
        border: 1px solid #333;
        border-bottom: 1px solid #333;
    }

    .el-tabs--card>.el-tabs__header .el-tabs__item {
        border-left: 1px solid #333;
    }

    .el-tabs__item {
        color: #999;
    }

    .el-tree {
        background-color: #222;
    }

    .is-current,
    .el-tree-node__content:hover {
        background-color: #333;
    }
</style>
<script>
    import request from "@/lib/request";
    export
        default {
            data() {
                return {
                    defaultProps: {
                        children: 'children',
                        label: 'label'
                    },
                    editor: false,
                    code: "",
                    namespace: "",
                    path: "",
                    head: "//static.hamm.cn/img/nohead.jpg",
                    repoInfo: false,
                    userInfo: false,
                    orgInfo: false,
                    treeData: [],
                    openFiles: [
                    ],
                    nowBranch: "Loading",
                    branchList: [],
                    firstFile:
                    {
                        sha: "xxx",
                        label: "GiteeInfo",
                        $treeNodeId: "0",
                        sha: "GiteeInfo"
                    },
                    selectedFileIndex: 0,
                    dontOpenOnEditor: [
                        "mp3", "mp4", "exe", "dll", "jpg", "jpeg", "png", "gif", "baml",
                        "zip", "rar", "7z", "tar", "xz", "mov", "amr", "rmvb", "mkv", "avi",
                        "ico", "dmg", "ipa", "apk", "iso", "ttf", "eot", "woff", "woff2"
                    ]
                }
            },
            created() {
                let that = this;
                let result = location.pathname.match(/\/(.*)\/(.*)?/);
                that.selectedFileIndex = that.firstFile.sha;
                if (result) {
                    that.namespace = result[1];
                    that.path = result[2];
                    that.getRepoInfo();
                } else {
                    that.$message.error("仓库数据查询失败");
                    setTimeout(function () {
                        that.$router.push('/');
                    }, 3000)
                }
            },
            mounted() {
                let that = this;
                that.editor = ace.edit("editor");// 这里不需要加 #
                that.editor.setTheme("ace/theme/monokai");//monokai
                that.editor.setOptions({
                    enableBasicAutocompletion: true,
                    enableSnippets: true,
                    enableLiveAutocompletion: true,//只能补全
                });
                that.editor.session.setUseWrapMode(true);
                that.editor.setHighlightActiveLine(true);
                // that.editor.setReadOnly(true);  // false to make it editable
                that.editor.getSession().setMode("ace/mode/html");//语言
                that.editor.setShowPrintMargin(false);
                that.openFile(that.firstFile);
            },
            methods: {
                removeOpenFile(sha) {
                    let that = this;
                    for (let i in that.openFiles) {
                        if (that.openFiles[i].sha == sha) {
                            that.openFiles.splice(i, 1);
                            if (that.openFiles.length == 0) {
                                that.openFile(that.firstFile);
                            } else {
                                if (i >= 1) {
                                    that.openFile(that.openFiles[i - 1]);
                                } else if (i == 0) {
                                    that.openFile(that.openFiles[0]);
                                }
                            }
                            break;
                        }
                    }
                },
                handleTabClick(e) {
                    let that = this;
                    for (let i in that.openFiles) {
                        if (that.openFiles[i].sha == e.name) {
                            that.openFile(that.openFiles[i]);
                            break;
                        }
                    }
                },
                handleNodeClick(data) {
                    if (data.type == "tree") {
                        data.children = [];
                        this.getTreeList(data, data.sha);
                    } else {
                        this.openFile(data);
                    }
                },
                handleBranchChanged(branch) {
                    let that = this;
                    that.nowBranch = branch;
                    that.treeData = [];
                    that.getTreeList(false, branch);
                },
                openFile(data) {
                    let that = this;
                    let isOpened = false;
                    if (that.openFiles.length == 1 && that.openFiles[0].sha == 'GiteeInfo') {
                        that.openFiles.splice(0, 1);
                    }
                    for (let i in that.openFiles) {
                        if (that.openFiles[i].sha == data.sha) {
                            isOpened = true;
                            break;
                        }
                    }
                    if (!isOpened) {
                        that.openFiles.push(data);
                    }
                    if (data.sha == 'GiteeInfo') {
                        that.selectedFileIndex = data.sha;
                        that.editor.getSession().setMode("ace/mode/markdown");//语言
                        that.editor.setValue(`# Hello Gitee.Info!`);
                        return;
                    }
                    request({
                        url: "repos/" + that.repoInfo.full_name + "/git/blobs/" + data.sha,
                        loading: true,
                        method: "GET",
                        data: {
                        },
                        success(res) {
                            var index = data.label.lastIndexOf(".");
                            var suffix = data.label.substr(index + 1).toLowerCase();
                            if (that.dontOpenOnEditor.indexOf(suffix) >= 0) {
                                that.$confirm('编辑器无法打开该文件,是否在浏览器打开?', '无法打开', {
                                    confirmButtonText: '确定',
                                    cancelButtonText: '取消',
                                    type: 'warning'
                                }).then(function () {
                                    window.open(data.url);
                                }).catch(function () {
                                });
                                return;
                            }
                            switch (suffix) {
                                case 'js':
                                case 'wxs':
                                    suffix = "javascript";
                                    break;
                                case 'cs':
                                case 'cpp':
                                case 'h':
                                    suffix = "csharp";
                                    break;
                                case 'wxml':
                                case 'vue':
                                    suffix = "html";
                                    break;
                                case 'wxss':
                                    suffix = "css";
                                    break;
                                case 'sln':
                                case 'yml':
                                    suffix = "yml";
                                    break;
                                case 'md':
                                    suffix = "markdown";
                                    break;
                                case 'sql':
                                    suffix = "mysql";
                                    break;
                                case 'php':
                                    suffix = "php";
                                    break;
                                case 'json':
                                    suffix = "json";
                                    break;
                                default:
                                    suffix = "html"
                            }
                            that.selectedFileIndex = data.sha;
                            // that.editor.getSession().setMode("ace/mode/csharp");//语言
                            that.editor.getSession().setMode("ace/mode/" + suffix);//语言
                            that.editor.setValue(Base64.decode(res.content));
                        }
                        , error(res) {
                            console.log(res);
                            that.$message.error("读取文件错误");
                        }
                    });

                },
                html2Escape(sHtml) {
                    return sHtml.replace(/[<>&"]/g, function (c) {
                        return {
                            '<': '&lt;',
                            '>': '&gt;',
                            '&': '&amp;',
                            '"': '&quot;'
                        }[c];
                    });
                },
                goToUserPage() {
                    if (this.namespace) {
                        this.$router.push('/' + this.namespace);
                    }
                    switch (this.repoInfo.namespace.type) {
                        case "personal":
                            this.$router.push('/' + this.userInfo.login);
                            break;
                        case 'group':
                            this.$router.push('/' + this.orgInfo.login);
                        default:
                    }
                },
                getUserInfo() {
                    let that = this;
                    request({
                        url: "users/" + that.repoInfo.namespace.path,
                        loading: true,
                        method: "GET",
                        data: {
                        },
                        success(res) {
                            that.head = res.avatar_url;
                            that.userInfo = res;
                        }
                        , error(res) {
                            that.$message.error("没有查询到指定的用户信息");
                            setTimeout(function () {
                                that.$router.push('/');
                            }, 3000)
                        }
                    });
                },
                getOrgInfo() {
                    let that = this;
                    request({
                        url: "orgs/" + that.repoInfo.namespace.path,
                        loading: true,
                        method: "GET",
                        data: {
                        },
                        success(res) {
                            that.head = res.avatar_url;
                            that.orgInfo = res;
                        }
                        , error(res) {
                            that.$message.error("没有查询到指定的用户信息");
                            setTimeout(function () {
                                that.$router.push('/');
                            }, 3000)
                        }
                    });
                },
                getTreeList(data = false, sha = false) {
                    let that = this;
                    if (!sha) {
                        sha = that.nowBranch;
                    }
                    request({
                        url: "repos/" + that.repoInfo.full_name + "/git/trees/" + sha + "?recursive=0",
                        loading: true,
                        method: "GET",
                        data: {
                        },
                        success(res) {
                            that.updateTree(data ? data.children : that.treeData, res.tree);
                        }
                        , error(res) {
                            console.log(res);
                            that.$message.error("没有查询到代码目录");
                        }
                    });
                },
                getBranchList() {
                    let that = this;
                    request({
                        url: "repos/" + that.repoInfo.full_name + "/branches",
                        loading: true,
                        method: "GET",
                        data: {
                        },
                        success(res) {
                            that.branchList = res;
                        }
                        , error(res) {
                            console.log(res);
                            that.$message.error("没有查询到代码目录");
                        }
                    });
                },
                updateTree(data, list) {
                    let that = this;
                    for (let i in list) {
                        if (list[i].type == 'blob') {
                            data.push({
                                url: list[i].url,
                                label: list[i].path,
                                sha: list[i].sha,
                                type: list[i].type
                            });
                        } else if (list[i].type == 'tree') {
                            data.push({
                                url: list[i].url,
                                label: list[i].path,
                                sha: list[i].sha,
                                type: list[i].type,
                                children: [
                                    {
                                        label: "Loading..."
                                    }
                                ]
                            });
                        }
                    }
                },
                getRepoInfo() {
                    let that = this;
                    if (!that.namespace || !that.path) {
                        that.$router.push('/');
                        return;
                    }
                    request({
                        url: "repos/" + that.namespace + "/" + that.path,
                        loading: true,
                        method: "GET",
                        data: {
                        },
                        success(res) {
                            that.repoInfo = res;
                            that.nowBranch = that.repoInfo.default_branch;
                            that.getTreeList();
                            that.getBranchList();
                            switch (res.namespace.type) {
                                case "personal":
                                    that.getUserInfo();
                                    break;
                                case 'group':
                                    that.getOrgInfo();
                                default:
                            }
                        },
                        error(res) {
                            this.$alert('请确认仓库地址是否正确,或该仓库是否为私有仓库', '查询仓库失败', {
                                confirmButtonText: '确定',
                                callback() {
                                    that.$router.push('/');
                                }
                            });
                        }
                    });
                }
            }
        }
</script>